1 module d_sysdlog.wrap;
2 
3 import d_sysdlog.bind;
4 import std.exception;
5 import std.stdio;
6 import std.conv;
7 import std.string;
8 import std.algorithm;
9 import std.array;
10 import core.stdc.stdlib;
11 import std.datetime;
12 
13 
14 enum useContainer=0;
15 
16 string ZtoString(const char* c)
17 {
18     if (c !is null)
19       return to!string(fromStringz(c));
20     else
21       return null;
22 }
23 
24 char* toZString(string s)
25 {
26 	char[] ret=cast(char[])s;
27 	if (ret[$-1]!='\0')
28 		ret~="\0";
29 	return ret.ptr;
30 }
31 
32 struct SystemDLog
33 {
34 	char[1024*100] buf;
35 	void *cp;
36 	int ret;
37 	sd_journal* journal=null;
38 
39 	this(int flags)
40 	{
41 		enforce((ret=sd_journal_open(&journal,flags))==0), // open all journal file types
42 			new Exception("Problem opening journal: error "~to!string(ret));
43 	}
44 
45 	this(string directory)
46 	{
47 		enforce((ret=sd_journal_open_directory(&journal,toZString(directory),0))==0), // open all journal file types
48 			new Exception("Problem opening journal: error "~to!string(ret));
49 	}
50 
51 	this(string[] files)
52 	{
53 		char*[] filelist;
54 		foreach(file;files)
55 			filelist~=toZString(file);
56 		filelist~=null;
57 		enforce((ret=sd_journal_open_files(&journal,cast(char**)&filelist,0))==0), // open all journal file types
58 			new Exception("Problem opening journal: error "~to!string(ret));
59 	}
60 
61 	~this()
62 	{
63 		sd_journal_close(journal);
64 		journal=null;
65 	}
66 
67 	version(useContainer) // in Fedora 21, not in earlier versions
68 	{
69 		void openContainer(string machine, int flags)
70 		{
71 			int err;
72 			if(journal !is null)
73 				sd_journal_close(journal);
74 			enforce((err=sd_journal_open_container(&journal,toZString(machine),flags))==0), // open all journal file types
75 				new Exception("Problem opening journal: error "~to!string(err));
76 			return;
77 		}
78 	}
79 	void filter(string match)
80 	{
81 		int err;
82 		enforce((err=sd_journal_add_match(journal,toZString(match),match.length)==0),
83 		 	new Exception("Problem opening journal: error "~to!string(ret)));
84 	}
85 
86 	void seekHead()
87 	{
88 		int err;
89 		enforce((err=sd_journal_seek_head(this.journal)==0),
90 	 		new Exception("Problem opening journal: error "~to!string(err)));
91 	}
92 
93 	void seekTail()
94 	{
95 		int err;
96 		enforce((err=sd_journal_seek_tail(this.journal)==0),
97 	 		new Exception("Problem opening journal: error "~to!string(err)));
98 	}
99 
100 	int seekNext()
101 	{
102 		int count;
103 		enforce(((count=sd_journal_next(this.journal))>=0),
104 	 		new Exception("Problem opening journal: error "~to!string(count)));
105 		return count;
106 	}
107 
108 	int seekNextSkip(ulong skip)
109 	{
110 		int count;
111 		enforce(((count=sd_journal_next_skip(this.journal,skip))>=0),
112 	 		new Exception("Problem opening journal: error "~to!string(count)));
113 		return count;
114 	}
115 
116 	int seekPrevious()
117 	{
118 		int count;
119 		enforce(((count=sd_journal_previous(this.journal))>=0),
120 	 		new Exception("Problem opening journal: error "~to!string(count)));
121 		return count;
122 	}
123 
124 	void seekMonotonic(sd_id128_t bootId, ulong usec)
125 	{
126 		int err;
127 		enforce(((err=sd_journal_seek_monotonic_usec(this.journal,bootId,usec))==0),
128 	 		new Exception("Problem opening journal: error "~to!string(err)));
129 		return;
130 	}
131 	void seekRealtime(ulong usec)
132 	{
133 		int err;
134 		enforce(((err=sd_journal_seek_realtime_usec(this.journal,usec))==0),
135 	 		new Exception("Problem opening journal: error "~to!string(err)));
136 		return;
137 	}
138 	
139 	string getCursor()
140 	{
141 		int err;
142 		char *cursor;
143 		enforce(((err=sd_journal_get_cursor(this.journal,&cursor))==0),
144 	 		new Exception("Problem opening journal: error "~to!string(err)));
145 		auto ret=ZtoString(cursor);
146 		free(cursor);
147 		return ret;
148 	}
149 	void seekCursor(string cursor)
150 	{
151 		int err;
152 		enforce(((err=sd_journal_seek_cursor(this.journal,toZString(cursor)))==0),
153 	 		new Exception("Problem opening journal: error "~to!string(err)));
154 		return;
155 	}
156 
157 	bool testCursor(string cursor)
158 	{
159 		int err;
160 		enforce(((err=sd_journal_test_cursor(this.journal,toZString(cursor)))>=0),
161 	 		new Exception("Problem opening journal: error "~to!string(err)));
162 		return(err>0);
163 	}
164 
165 	int seekPreviousSkip(ulong skip)
166 	{
167 		int count;
168 		enforce(((count=sd_journal_previous_skip(this.journal,skip))>=0),
169 	 		new Exception("Problem opening journal: error "~to!string(count)));
170 		return count;
171 	}
172 
173 
174 	string getFieldData(string field)
175 	{
176 		int err;
177 		ubyte[100*1024] buf;
178 		void *cp;
179 		size_t size=buf.sizeof;
180 		cp=cast(void*)buf.ptr;
181 		enforce((err=sd_journal_get_data(journal,toZString(field),cast(void**)&cp,&size))==0),
182 	 		new Exception("Problem opening journal: error "~to!string(err));
183 	 	return ZtoString(cast(const char*)((cast(char*)(cp))[0..size]~'\0'));
184 	 }
185 
186 	string[string] getRecord()
187 	{
188 		string[string] ret;
189 		ubyte[100*1024] buf;
190 		void *cp;
191 		size_t size=buf.sizeof;
192 		cp=cast(void*)buf.ptr;
193 	         	size_t l=buf.sizeof;
194 	         	for (sd_journal_restart_data(journal); (sd_journal_enumerate_data(journal, cast(void**)&cp,&(l)) > 0); )
195 	         	{
196 	         		string s=ZtoString(cast(const char*)((cast(char*)(cp))[0..l]~'\0'));
197 	         		auto sSplit=split(s,"=");
198 	         		if (s.length>=2)
199 	         			ret[sSplit[0]]=join(sSplit[1..$],"=");
200 	         		l=buf.sizeof;
201 	         		cp=cast(void*)buf.ptr;
202 	         	}
203 	         	return ret;
204 	 }
205 }